from PIL import Image, ImageFilter
from grapefruit import Color
from vec import dist, sqrdist, sumsqrs

EPSILON = .001

def blur(im):
	return im.filter(ImageFilter.BLUR)
	
def getPatch(mat, x, y, size = 9):
	m = []
	offset = (size - 1) / 2
	for i in range(x - offset, x + offset + 1):
		col = []
		for j in range(y - offset, y + offset + 1):
			col.append(mat[i][j])
		m.append(col)
		
	return m

def getLPatch(mat, x, y, size = 9):
	# assumes mat is lab matrix
	m = []
	offset = (size - 1) / 2
	for i in range(x - offset, x + offset + 1):
		col = []
		for j in range(y - offset, y + offset + 1):
			col.append(mat[i][j][0])
		m.append(col)

	return m
	
def getLabPatch(mat, x, y, size = 9):
	# assumes mat is lab matrix
	# makes colors l,a*50,b*50
	m = []
	offset = (size - 1) / 2
	for i in range(x - offset, x + offset + 1):
		col = []
		for j in range(y - offset, y + offset + 1):
			c = mat[i][j]
			col.append((c[0],c[1]*50,c[2]*50))
		m.append(col)
		
	return m
	
def confidenceTerm(mat, x, y, size=9):
	C = 0
	offset = (size - 1) / 2
	for i in range(x - offset, x + offset + 1):
		for j in range(y - offset, y + offset + 1):
			C += mat[i][j]
			
	return C / float(size * size)

def listToImage(l):
	im = Image.new("RGB", (len(l), len(l[0])))
	im.format = "PPM"
	pix = im.load()
	for x, row in enumerate(l):
		for y, color in enumerate(row):
			pix[x,y] = color
	return im

def imageToList(im):
	l = []
	pix = im.load()
	for x in range(im.size[0]):
		r = []
		for y in range(im.size[1]):
			r.append(pix[x,y])
		l.append(r)
	return l
	
def RgbToLab(rgb, rgb_max=255):
	r, g, b = rgb
	x, y, z = Color.RgbToXyz(r/float(rgb_max), 
							 g/float(rgb_max), 
							 b/float(rgb_max))
	l, a, b = Color.XyzToLab(x, y, z)
	return (l, a, b)
	
def LabToRgb(lab, rgb_max=255):
	l, a, b = lab
	x, y, z = Color.LabToXyz(l, a, b)
	r, g, b = Color.XyzToRgb(x, y, z)
	return (int(rgb_max*r), int(rgb_max*g), int(rgb_max*b))
	
def RgbToGrey(rgb, rgb_max=255):
	r, g, b = rgb
	grey = Color.RgbToGreyscale(r/float(rgb_max), 
					      		g/float(rgb_max), 
						  		b/float(rgb_max))[0]
	return grey
	
# def RgbToLab(rgb, rgb_max=255):
# 	r,g,b = rgb
# 	x=.412453*r+.357580*g+.180423*b
# 	y=.212671*r+.715160*g+.072169*b
# 	z=.019334*r+.119193*g+.950227*b
# 	X,Y,Z = .95045,1,1.088754
# 	x3 = (x/X)**(1/3.)
# 	y3 = (y/Y)**(1/3.)
# 	z3 = (z/Z)**(1/3.)
# 	L=116*y3
# 	a=500*(x3-y3)
# 	b=200*(y3-z3)
# 	return (int(L),int(a),int(b))
# 	
# def LabToRgb(lab):
# 	L,a,b = lab
# 	y3=L/116.0
# 	x3=a/500.+y3
# 	z3=b/(-200.0)+y3
# 	X,Y,Z = .95045,1,1.088754
# 	x=x3**3*X
# 	y=y3**3*Y
# 	z=z3**3*Z
# 	r=3.24048134*x+(-1.53715152)*y+(-.49853633)*z
# 	g=(-.96925495)*x+1.87599*y+.04155593*z
# 	b=.05564664*x+(-.20404134)*y+1.05731107*z
# 	return (int(r+.5),int(g+.5),int(b+.5))
	
def colorDiff(p1, p2):
	size = len(p1)
	total = 0.0
	for i in range(size):
		for j in range(size):
			if not isBlack(p1, i, j) and not isBlack(p2, i, j):
				total += sqrdist(p1[i][j], p2[i][j])
	return total
	
def fillPatch(mat, p, x, y):
	size = len(p)
	filled = []
	for i in range(size):
		xpos = x - (size - 1) / 2 + i
		for j in range(size):
			ypos = y - (size - 1) / 2 + j
			if isBlack(mat, xpos, ypos):
				mat[xpos][ypos] = p[i][j]
				filled.append((xpos, ypos))
				
	return filled
				
				
def isBlack(l, i, j):
	c = l[i][j]
	return dist(c,(0.0,0.0,0.0)) < EPSILON